package com.echo.code.thread.lock.impl;

import com.echo.code.thread.lock.Lock;
import com.echo.code.thread.lock.helper.impl.ReadWriteLockHelperImpl;
import java.util.concurrent.TimeoutException;
import java.util.logging.Logger;

/**
 * ReadLock Created by baiyap on 2018/9/24.
 */
public class ReadLock implements Lock {

  private static final Logger LOGGER = Logger.getLogger(ReadLock.class.getName());

  private final ReadWriteLockHelperImpl helper;

  public ReadLock(ReadWriteLockHelperImpl helper) {
    this.helper = helper;
  }

  @Override
  public void lock() throws InterruptedException {
    synchronized (helper.getMutex()) {
      while (helper.getWritingWriters() > 0 || (helper.getWaitingWriters() > 0 && helper.isPreferWriter())) {
        LOGGER.info(getCurrentThreadName() + "can not get the read lock and suspend...");
        try {
          helper.getMutex().wait();
        } catch (InterruptedException e) {
          throw e;
        }
      }
      LOGGER.info(getCurrentThreadName() + " obtain the read lock.");
      helper.incrementReadingReaders();
    }
  }

  @Override
  public void unlock() {
    synchronized (helper.getMutex()) {
      LOGGER.info(getCurrentThreadName() + " release the read lock.");
      helper.decrementReadingReaders();
      helper.changePreferWriter(Boolean.TRUE);
      helper.getMutex().notifyAll();
    }
  }

  @Override
  public void lock(long mills) throws InterruptedException, TimeoutException {
    // TODO
  }
}
